package com.jnxx.task.service.impl;

import com.jnxx.task.domain.ShopReport;
import com.jnxx.task.dto.ReportDto;
import com.jnxx.task.dto.ReportFormDto;
import com.jnxx.task.dto.SeriesItem;
import com.jnxx.task.mapper.ShopReportMapper;
import com.jnxx.task.service.IShopReportService;
import com.jnxx.task.vo.ReportVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * shopReportService业务层处理
 * 
 * @author sh
 * @date 2024-01-08
 */
@Service
public class ShopReportServiceImpl implements IShopReportService 
{
    @Autowired
    private ShopReportMapper shopReportMapper;

    /**
     * 查询shopReport
     * 
     * @param id shopReport主键
     * @return shopReport
     */
    @Override
    public ShopReport selectShopReportById(Long id)
    {
        return shopReportMapper.selectShopReportById(id);
    }

    /**
     * 查询shopReport列表
     * 
     * @param shopReport shopReport
     * @return shopReport
     */
    @Override
    public List<ShopReport> selectShopReportList(ShopReport shopReport)
    {
        return shopReportMapper.selectShopReportList(shopReport);
    }

    /**
     * 新增shopReport
     * 
     * @param shopReport shopReport
     * @return 结果
     */
    @Override
    public int insertShopReport(ShopReport shopReport)
    {
        return shopReportMapper.insertShopReport(shopReport);
    }

    /**
     * 修改shopReport
     * 
     * @param shopReport shopReport
     * @return 结果
     */
    @Override
    public int updateShopReport(ShopReport shopReport)
    {
        // 获取创建时间
        LocalDate taskTime = shopReport.getTaskTime();
        // 任务创建的时间
        LocalDateTime creatDateTime = taskTime.atStartOfDay();

        // 获取当前日期时间
        LocalDateTime nowTime = LocalDateTime.now();
        // 获取今天的11点
        LocalDateTime today11AM = LocalDateTime.of(nowTime.toLocalDate(), LocalTime.of(11, 0));


        // 11点之前，正常完成任务，之后就是超时完成任务
        if (today11AM.isAfter(nowTime)) {
            // 按时
            shopReport.setStatus("1");
        } else {
            // 超时
            shopReport.setStatus("2");
        }
        // 获取下周一的11点
        LocalDateTime nextMondayAtEleven = creatDateTime
                .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY)) // 下周一
                .withHour(11) // 设置小时为11
                .withMinute(0) // 设置分钟为0
                .withSecond(0); // 设置秒为0

        // 获取创建任务时间是周几
        DayOfWeek creatOfWeek = creatDateTime.getDayOfWeek();

        // 判断是否是周六或周日
        if (creatOfWeek == DayOfWeek.SATURDAY || creatOfWeek == DayOfWeek.SUNDAY) {
            // 是周六周天的话，只要在下周1，11点之前提交，都算按时完成
            if (nextMondayAtEleven.isAfter(nowTime)){
                shopReport.setStatus("1");
            }
        }
        shopReport.setFinishTime(new Date());
        return shopReportMapper.updateShopReport(shopReport);
    }

    /**
     * 批量删除shopReport
     * 
     * @param ids 需要删除的shopReport主键
     * @return 结果
     */
    @Override
    public int deleteShopReportByIds(Long[] ids)
    {
        return shopReportMapper.deleteShopReportByIds(ids);
    }

    /**
     * 删除shopReport信息
     * 
     * @param id shopReport主键
     * @return 结果
     */
    @Override
    public int deleteShopReportById(Long id)
    {
        return shopReportMapper.deleteShopReportById(id);
    }

    /**
     * 根据负责人id和时间获取汇报任务
     * @param reportVo
     * @return
     */
    @Override
    public List<ShopReport> getByStaffIdAndTime(ReportVo reportVo) {

//        changeTimeToLocalDataTime(reportVo);

        return shopReportMapper.getByStaffIdAndTime(reportVo);
    }

    // 将接收的str时间转换
//    private static void changeTimeToLocalDataTime(ReportVo reportVo) {
//        LocalDate startTimeLD = LocalDate.parse(startTimeStr, DateTimeFormatter.ISO_DATE);
//        LocalDate endTimeLD = LocalDate.parse(endTimeStr, DateTimeFormatter.ISO_DATE);
//        LocalDateTime startTime = LocalDateTime.of(startTimeLD, LocalTime.MIN);
//        LocalDateTime endTime = LocalDateTime.of(endTimeLD, LocalTime.MIN);
//        // 将开始和结束时间转换为LocalDateTime类型，方便搜索
//        reportVo.setStartTime(startTime);
//        reportVo.setEndTime(endTime);
//    }

    /**
     * 查询指定时间段内，所有店铺 GMV 和 利润 总和 柱状图
     * @param reportVo
     * @return
     */
    @Override
    public ReportDto getAllReportForStatistics(ReportVo reportVo) {
        reportVo.setStatus("10");
        // 查到这个时间内的所有完成数据
        List<ShopReport> byStaffIdAndTime = getByStaffIdAndTime(reportVo);
        // 最终返回的对象
        ReportDto reportDto = new ReportDto();

        // reportDto中的series
        ArrayList<SeriesItem> series = new ArrayList<>();
        // 按照每个店铺分类
            Map<String, List<ShopReport>> groupedByShopId = byStaffIdAndTime.stream()
                .collect(Collectors.groupingBy(e->e.getShop().getName()));
        // 店铺名称
        List<String> shopNamesList = new ArrayList<>();
        //  每个seriesItem中的GMV
        SeriesItem seriesItem = new SeriesItem();
        // 每个seriesItem中的GMV的data
        List<BigDecimal> gmvList = new ArrayList<>();

        //  每个seriesItem中的利润
        SeriesItem seriesItem2 = new SeriesItem();
        // 每个seriesItem中的利润的data
        List<BigDecimal> profitList =new ArrayList<>();

        // 遍历 每种店铺 中的元素，获取GMV和利润的平均值，然后设置到data
        groupedByShopId.forEach((shopName, shopReports) -> {
            shopNamesList.add(shopName);
            BigDecimal totalGMV = shopReports.stream()
                    .map(ShopReport::getGmv)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            gmvList.add(totalGMV);

            BigDecimal totalProfit = shopReports.stream()
                    .map(ShopReport::getProfit)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            profitList.add(totalProfit);
        });

        seriesItem.setName("GMV");
        seriesItem.setData(gmvList);
        series.add(seriesItem);;

        seriesItem2.setName("利润");
        seriesItem2.setData(profitList);
        series.add(seriesItem2);
        reportDto.setSeries(series);
        reportDto.setCategories(shopNamesList);
        return reportDto;
    }

    /**
     * 获取所有时间段内未延迟完成的汇报
     * @param reportVo
     * @return
     */
    @Override
    public List<ShopReport> getReportDelay(ReportVo reportVo) {

//         changeTimeToLocalDataTime(reportVo);
        return shopReportMapper.getReportDelay(reportVo);
    }

    /**
     * 获取表格数据
     * @param reportVo
     * @return
     */
    @Override
    public List<ReportFormDto> getReportform(ReportVo reportVo) {
//        changeTimeToLocalDataTime(reportVo);
        reportVo.setStatus("10");
        // 查到这个时间内的所有完成数据
        List<ShopReport> byStaffIdAndTime = getReportDelay(reportVo);
        // 按照每个店铺分类
        Map<String, List<ShopReport>> groupedByShopId = byStaffIdAndTime.stream()
                .collect(Collectors.groupingBy(e->e.getShop().getName()));

        ArrayList<ReportFormDto> formDtos = new ArrayList<>();

        groupedByShopId.forEach((shopName, shopReports) -> {
            ReportFormDto reportFormDto = new ReportFormDto();
            BigDecimal totalGMV = shopReports.stream()
                    .map(ShopReport::getGmv)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal totalProfit = shopReports.stream()
                    .map(ShopReport::getProfit)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            reportFormDto.setName(shopName);
            reportFormDto.setHeadName(shopReports.get(0).getHeadName());
            reportFormDto.setGmvSum(totalGMV);
            reportFormDto.setProfitSum(totalProfit);
            formDtos.add(reportFormDto);
        });
        return formDtos;
    }

    @Override
    public List<ShopReport> selectShopListByStatus(String status) {
        return shopReportMapper.selectShopListByStatus(status);
    }
}
